#!/usr/bin/env perl
# Check daily snapshots are working & complain if unsnapshotted filesystems exist


use lib "/usr/monitoring_scripts/lib/";
use Getopt::Std;
use Data::Dumper;
use Time::Local;
use HTTP::Date;

my $threshhold, $cur_epoch = time(), $debug = 0;
my %allsnapshots, %nosnaps, %newestsnapshots, %fscreate;
my @zfsoutput, @excludes, @unqfs, @nosnaps, @oldsnaps;

sub grab_input {
        open(ZFSLIST, "/usr/sbin/zfs list -r -o name,creation,mountpoint |");
        while(<ZFSLIST>) {
                push (@zfsoutput, $_);
        }

        close (ZFSLIST);
}

sub find_unqfs {
	foreach (@zfsoutput) {
		chomp; next if ($_ =~ /NAME/); 
		@tmp = split(/\s{3,}/, $_);
		$tmp[1] =~ s/\s-$//;
		$fscreate{$tmp[0]} = $tmp[1] if ($_ =~ /\@/);
        	push (@unqfs, $tmp[0]) unless ($_ =~ /\@/);
	}
}

sub find_exclude {
	foreach (@zfsoutput) {
		chomp; next if ($_ =~ /\@/); next if ($_ =~ /NAME/);
		@tmp = split(/\s{3,}/, $_); $tmp[1] =~ s/\s-$//;
		push (@excludes, $tmp[0]) if ($_ =~ /none/);
		if ($debug) {
			print "[*] Added $tmp[0] to exclude list as mountpoint=none\n" if ($_ =~ /none/);
		}
	}

        open(EXCLUDE, "/etc/backup/exclude");
        while(<EXCLUDE>) {
		chomp;
                push (@excludes, $_);
		print "[*] Added $_ to exclude list from excludes file\n" if $debug; 
        }
        close (EXCLUDE);

	undef %is_excluded; for (@excludes) { $is_excluded{$_} = 1; }
}

sub find_sn {
        foreach $fs (@unqfs) {     
		foreach (@zfsoutput) {
			next unless ($_ =~ /$fs\@daily/);
			@tmp = split(/\s/, $_);
                	push @{ $allsnapshots{$fs} }, $tmp[0];
        	}
	}

	# RM Excludes from snapshot list
	foreach(@excludes) { chomp; delete $allsnapshots{$_}; }

	# Only take the newest daily- snapshot
	foreach $fs (keys %allsnapshots) {
		$newestsnapshots{$fs} = $allsnapshots{$fs}[-1];
	}

}

sub find_nosnaps {
	 foreach (@unqfs) {
		 if ($is_excluded{$_}) { 
			 print "[*] No Snapshots for $_ ignored as it's part of the exclude list\n" if $debug;
		 } else {
			 push (@nosnaps, $_) unless $newestsnapshots{$_};
		 }
	 }

	 if ($debug) {
		 foreach (@nosnaps) {
			 print "[*] No snapshots for $_\n";
	 	 } 
	 }
}

sub find_oldsnaps {
	foreach $fs (keys %newestsnapshots) {
		$time = str2time($fscreate{$newestsnapshots{$fs}});
		my $diff = $cur_epoch - $time;
		if ($diff > 864500) {
			push (@oldsnaps, $fs);
			print "[!] Snapshot $fs is $diff too old\n" if $debug;
		}

	}
}

getopt('d'); $debug = $opt_d;

grab_input;
find_unqfs;
find_exclude;
find_sn;
find_nosnaps;
find_oldsnaps;

if (@nosnaps) {
	print "1\n";
	exit 1;
}

if (@oldsnaps) {
	print "1\n";
	exit 1;
}

print "0\n";

# print Dumper(%newestsnapshots);
